{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "multiple_input_CNN.ipynb",
      "provenance": [],
      "collapsed_sections": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/HasikaR/Audio-Denoising-Deep-Learning/blob/main/multiple_input_CNN.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "qx1QyFWS_jU-",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "bd4584b8-d0e4-4af5-97c5-0cff0b76dc5b"
      },
      "source": [
        "%tensorflow_version 1.x"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "TensorFlow 1.x selected.\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "hdHFHoH55ImO"
      },
      "source": [
        "import librosa\n",
        "import numpy as np\n",
        "import matplotlib.pyplot as plt\n",
        "import tensorflow as tf\n",
        "import random\n",
        "import copy"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "1qmFH5zPoz-V"
      },
      "source": [
        "import glob\n",
        "import zipfile"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5CJuEY2GEOGq"
      },
      "source": [
        "gpu_options = tf.compat.v1.GPUOptions(allow_growth = True)\n",
        "config=tf.compat.v1.ConfigProto(gpu_options=gpu_options)\n",
        "config.gpu_options.per_process_gpu_memory_fraction = 0.34"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "svj9wfaw6XQa",
        "outputId": "ce02a880-c864-4219-f4c9-7f1cf8d58f6a"
      },
      "source": [
        "from google.colab import drive\n",
        "drive.mount('/content/drive')"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Mounted at /content/drive\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "iEEXpiTyn0bv"
      },
      "source": [
        "max_length = 1126"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "6Buu49d4OOaq"
      },
      "source": [
        "with zipfile.ZipFile('/content/drive/MyDrive/s6.zip', 'r') as zip_ref:\n",
        "    zip_ref.extractall('/tmp')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VnDQv00aOSkw"
      },
      "source": [
        "with zipfile.ZipFile('/content/drive/MyDrive/c6.zip', 'r') as zip_ref:\n",
        "    zip_ref.extractall('/tmp2')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SpundZbun3Bj"
      },
      "source": [
        "def getData( input_data_path):\n",
        " \n",
        "    speech_list = []\n",
        "    mag_speech_list = []\n",
        "    for file in sorted(glob.iglob(input_data_path)):\n",
        "      s,sr = librosa.load(file , sr=None)\n",
        "      S = librosa.stft(s, n_fft=1024, hop_length=512)\n",
        "      stft_len = S.shape[1]\n",
        "      S = np.pad(S, ((0,0),(0, max_length-stft_len)), 'constant')\n",
        "      speech_list.append(S)\n",
        " \n",
        "      mag_S = np.abs(S)\n",
        "      mag_speech_list.append(mag_S)\n",
        "    \n",
        "    return speech_list , mag_speech_list"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SvfqOHirn5gA"
      },
      "source": [
        "clean_speech_data_path = '/tmp2/c6/*.wav'\n",
        "#/content/drive/MyDrive/inputs_clean\n",
        "clean_speech_list, mag_clean_speech_list = getData( clean_speech_data_path)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "lHTDN9sen7xl"
      },
      "source": [
        "mag_clean_speech_list=np.array(mag_clean_speech_list)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "9Xnd3cvtn-LI",
        "outputId": "d713b2bb-494d-4429-aaac-fa88c80be988"
      },
      "source": [
        "print(mag_clean_speech_list.shape)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(36, 513, 1126)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EsOx8jiJU6-H"
      },
      "source": [
        "def getData1( input_data_path):\n",
        " \n",
        "    speech_list = []\n",
        "    mag_speech_list = []\n",
        "    for file in sorted(glob.iglob(input_data_path)):\n",
        "      s,sr = librosa.load(file , sr=None)\n",
        "      X = librosa.stft(s, n_fft=1024, hop_length=512)\n",
        "      stft_len = X.shape[1]\n",
        "      X = np.pad(X, ((0,0),(0, max_length-stft_len)), 'constant')\n",
        "      speech_list.append(X)\n",
        " \n",
        "      mag_X = np.abs(X)\n",
        "      mag_speech_list.append(mag_X)\n",
        "    \n",
        "    return speech_list , mag_speech_list"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "REfgdHMooAwB"
      },
      "source": [
        "mixed_speech_data_path = '/tmp/s6/*.wav'\n",
        "#/content/drive/MyDrive/inputs\n",
        "mixed_speech_list, mag_mixed_speech_list = getData1(mixed_speech_data_path)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ZC-l7OIIoDH0"
      },
      "source": [
        "mag_mixed_speech_list=np.array(mag_mixed_speech_list)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "QYQkZZHNTMCF",
        "outputId": "78c66996-e2e6-416c-9b5c-1fed438d5043"
      },
      "source": [
        "print(mag_mixed_speech_list.shape)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(36, 513, 1126)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uwsFX5n0oFIf"
      },
      "source": [
        "mag_mixed_speech_list=mag_mixed_speech_list.reshape(513,36*1126)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SyweUlpwoHKL"
      },
      "source": [
        "mag_clean_speech_list=mag_clean_speech_list.reshape(513,36*1126)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "z3bnDvfhoI-f"
      },
      "source": [
        "x_test, sr = librosa.load('/content/drive/MyDrive/dnn/ss441_cs15_kd21.wav', sr=None)\n",
        "X_test = librosa.stft(x_test, n_fft=1024, hop_length=512)\n",
        "\n",
        "x_test2, sr = librosa.load('/content/drive/MyDrive/dnn/ss670_cs23_kd10.wav', sr=None)\n",
        "X_test2 = librosa.stft(x_test2, n_fft=1024, hop_length=512)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "mnPmSv7p_Zsv"
      },
      "source": [
        "mag_S = mag_clean_speech_list\n",
        "mag_X = mag_mixed_speech_list\n",
        "mag_X_test = np.abs(X_test)\n",
        "mag_X_test2 = np.abs(X_test2)\n",
        "\n",
        "#Defining model specifications\n",
        "learning_rate = 0.0002\n",
        "num_epochs = 2000\n",
        "batch_size = 64\n",
        "window_size = 20"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "uxlt0uU5_emX"
      },
      "source": [
        "input = tf.compat.v1.placeholder(tf.float32, [None, 513])\n",
        "labels = tf.compat.v1.placeholder(tf.float32, [None, 513])"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "x3FTegxP_9E8"
      },
      "source": [
        "def getModel(x):\n",
        "  # Input Layer\n",
        "  input_layer = tf.reshape(x, [-1, 20, 513, 1])\n",
        "\n",
        "  # Convolutional Layer #1\n",
        "  conv1 = tf.layers.conv2d(\n",
        "      inputs=input_layer,\n",
        "      filters=16,\n",
        "      kernel_size=[4,4],\n",
        "      padding=\"same\",\n",
        "      activation=tf.nn.relu)\n",
        "\n",
        "  # Pooling Layer #1\n",
        "  pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2,2], strides=[2,2])\n",
        "\n",
        "  # Convolutional Layer #2 and Pooling Layer #2\n",
        "  conv2 = tf.layers.conv2d(\n",
        "      inputs=pool1,\n",
        "      filters=32,\n",
        "      kernel_size=[2,2],\n",
        "      padding=\"same\",\n",
        "      activation=tf.nn.relu)\n",
        "  \n",
        "  pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2,2], strides=[2,2])\n",
        "\n",
        "  # Dense Layer\n",
        "  pool2_flat = tf.layers.flatten(pool2)\n",
        "  \n",
        "  logits = tf.layers.dense(inputs=pool2_flat, units=513, activation=tf.nn.relu)\n",
        "  \n",
        "  return logits"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "bTSdJnBuAH67"
      },
      "source": [
        "def transform_data(x , size , window_size):\n",
        "  temp = x[0 : 0 + window_size,:]\n",
        "  for i in range(1 , size - window_size + 1):\n",
        "      temp_mini = x[i : i + window_size,:]\n",
        "      temp = np.vstack((temp , temp_mini))\n",
        "      \n",
        "  return temp"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "rlhj63T2NzJq"
      },
      "source": [
        "#DO NOT RUN THE NEXT 4 LINES AFTER EXECUTING FOR THE 1 ST TIME"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wktoOKLcAK5j"
      },
      "source": [
        "transformed_x = transform_data(mag_X.T , np.shape(mag_X.T)[0] , window_size)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "fKodMZ45H9kg",
        "outputId": "3bf99fe1-5fad-44c8-e6fd-289b75f84f6f"
      },
      "source": [
        "print(type(transformed_x))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'numpy.ndarray'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cp7oeHPSNJjp",
        "outputId": "906747fa-d68a-44c3-93d2-1b78f478f805"
      },
      "source": [
        "print(transformed_x.shape)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(810340, 513)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "zIccLpNSJyHm"
      },
      "source": [
        "np.savetxt(\"/content/drive/MyDrive/transform.txt\",transformed_x , delimiter=';', fmt='%s')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "D-dwYiF_u9Ht"
      },
      "source": [
        "transformed_x=np.loadtxt(\"/content/drive/MyDrive/transform.txt\",delimiter=';')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5VwRLlw9vEQf"
      },
      "source": [
        "Execute from this line"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Jc4unqLdKKbv"
      },
      "source": [
        ""
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "cLyvGXC-ASi4"
      },
      "source": [
        "transformed_x1 = copy.deepcopy(transformed_x)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FBbZmP9kAVeK"
      },
      "source": [
        "transformed_x = np.reshape(transformed_x , (40517, 20 , 513))"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TUeipmwrAYPq"
      },
      "source": [
        "transformed_y = (mag_S.T)[window_size - 1 : , :]"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1hxjfSA3Add0",
        "outputId": "0b915e83-6d2e-4d5f-dc8b-5d36cfc873a8"
      },
      "source": [
        "output = getModel(input)\n",
        "#Defining the loss function along with its optimizer\n",
        "loss = tf.reduce_mean(tf.square(output - labels))\n",
        "train_step = tf.train.AdamOptimizer(learning_rate).minimize(loss)\n",
        "\n",
        "sess = tf.InteractiveSession()\n",
        "sess.run(tf.global_variables_initializer())\n",
        "\n",
        "count = 0\n",
        "flag = True\n",
        "c=[]\n",
        "l=[]\n",
        "while flag:\n",
        "    size = 0\n",
        "    #Mini batching with the given batch size\n",
        "    for i in range(0 , 40517, batch_size):\n",
        "        size += batch_size\n",
        "        if size <= 40517:\n",
        "            batch_x = transformed_x[i : size, :]\n",
        "            batch_y = transformed_y[i : size, :]\n",
        "        else:\n",
        "            batch_x = transformed_x[i : 40517, :]\n",
        "            batch_y = transformed_y[i : 40517, :]\n",
        "        \n",
        "        \n",
        "        batch_x = batch_x.reshape((np.shape(batch_x)[0] * np.shape(batch_x)[1] , np.shape(batch_x)[2]))\n",
        "        #print(batch_y.shape)\n",
        "        feed_dict = {input: batch_x, labels: batch_y}\n",
        "        train_step.run(feed_dict=feed_dict)\n",
        "\n",
        "    if count%2 == 0:\n",
        "        loss_calc = loss.eval(feed_dict=feed_dict)\n",
        "        print(\"Epoch %d, loss %g\"%(count, loss_calc))\n",
        "        c.append(count)\n",
        "        l.append(loss_calc)\n",
        "    \n",
        "    #Once all the epochs are completed, training is stopped\n",
        "    if count >= 30:\n",
        "        flag = False  \n",
        "        \n",
        "    count+=1"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "WARNING:tensorflow:From <ipython-input-21-313388ed2fdd>:11: conv2d (from tensorflow.python.layers.convolutional) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Use `tf.keras.layers.Conv2D` instead.\n",
            "WARNING:tensorflow:From /tensorflow-1.15.2/python3.7/tensorflow_core/python/layers/convolutional.py:424: Layer.apply (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Please use `layer.__call__` method instead.\n",
            "WARNING:tensorflow:From <ipython-input-21-313388ed2fdd>:14: max_pooling2d (from tensorflow.python.layers.pooling) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Use keras.layers.MaxPooling2D instead.\n",
            "WARNING:tensorflow:From <ipython-input-21-313388ed2fdd>:27: flatten (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Use keras.layers.flatten instead.\n",
            "WARNING:tensorflow:From <ipython-input-21-313388ed2fdd>:29: dense (from tensorflow.python.layers.core) is deprecated and will be removed in a future version.\n",
            "Instructions for updating:\n",
            "Use keras.layers.Dense instead.\n",
            "Epoch 0, loss 1.18859e-07\n",
            "Epoch 2, loss 0\n",
            "Epoch 4, loss 0.0240728\n",
            "Epoch 6, loss 0.0209792\n",
            "Epoch 8, loss 0.0135596\n",
            "Epoch 10, loss 0.00834461\n",
            "Epoch 12, loss 0.00453327\n",
            "Epoch 14, loss 0.00199938\n",
            "Epoch 16, loss 0.00103264\n",
            "Epoch 18, loss 0.000825532\n",
            "Epoch 20, loss 0.000626801\n",
            "Epoch 22, loss 0.000527282\n",
            "Epoch 24, loss 0.000351725\n",
            "Epoch 26, loss 0.000401519\n",
            "Epoch 28, loss 0.000557517\n",
            "Epoch 30, loss 8.46201e-05\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 312
        },
        "id": "EhyjSGP3FXgp",
        "outputId": "14336c30-4bcf-41b8-c2e5-29d76d63ae1f"
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "plt.title(\"Result Analysis-Loss calculation for Audio Denoising\")\n",
        "      \n",
        "# label of x-axis\n",
        "plt.xlabel(\"Epoch\")\n",
        "\n",
        "plt.ylabel(\"Loss\")\n",
        "\n",
        "  \n",
        "# actual ploting\n",
        "plt.plot(c, l)\n",
        "  \n",
        "# shows the plot \n",
        "# in new wind"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "[<matplotlib.lines.Line2D at 0x7f697521ebd0>]"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 44
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": [],
            "needs_background": "light"
          }
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "fJZhpQuO7Pq0",
        "outputId": "e5c032ed-28ce-4c5f-cb55-2f861d74fe5b"
      },
      "source": [
        "print(type(output))"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "<class 'tensorflow.python.framework.ops.Tensor'>\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "sUr_Maz5ABI2",
        "outputId": "449759aa-f337-4bc8-a08f-1e8857be3b75"
      },
      "source": [
        "print(output.shape)"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "(?, 513)\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "8esNH0aCBHJE"
      },
      "source": [
        "def feedforward(input_data, dnn_output):\n",
        "    output = dnn_output.eval(feed_dict = {input : input_data})\n",
        "    \n",
        "    return output\n",
        "\n",
        "#Recovering the complex values of the file from the output of the model\n",
        "def recover_sound(X , mag_X , mag_output):\n",
        "  temp = X / mag_X\n",
        "  s_hat = temp * mag_output\n",
        "  \n",
        "  return s_hat\n",
        "\n",
        "#Recovering the lost frames\n",
        "def recover_data(x , size , value):\n",
        "  temp = np.full(size , value)\n",
        "  output = np.vstack((temp , x))\n",
        "  \n",
        "  return output"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "3JEKOBKnBNok"
      },
      "source": [
        "transformed_x_test = transform_data(mag_X_test.T , np.shape(mag_X_test.T)[0] , window_size)\n",
        "transformed_x_test2 = transform_data(mag_X_test2.T , np.shape(mag_X_test2.T)[0] , window_size)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XLX62OaSBQbn"
      },
      "source": [
        "s_hat_test1 = feedforward(transformed_x_test , output)\n",
        "s_hat_test2 = feedforward(transformed_x_test2 , output)\n",
        "\n",
        "#Recovering the first 19 frames that were lost\n",
        "recovered_x_test1 = recover_data(s_hat_test1 , (window_size - 1 , np.shape(s_hat_test1)[1]) , 1e-15)\n",
        "recovered_x_test2 = recover_data(s_hat_test2 , (window_size - 1 , np.shape(s_hat_test2)[1]) , 1e-15)\n",
        "\n",
        "#Recovering the complex values of both the test files\n",
        "s_hat1 = recover_sound(X_test , mag_X_test , recovered_x_test1.T)\n",
        "s_hat2 = recover_sound(X_test2 , mag_X_test2 , recovered_x_test2.T)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "29S2b9l0BWkX"
      },
      "source": [
        "import soundfile as sf\n",
        "recon_sound = librosa.istft(s_hat1 , hop_length=512 , win_length=1024)\n",
        "sf.write('/content/drive/MyDrive/cnn_output/cnn_01.wav', recon_sound,sr)\n",
        "recon_sound2 = librosa.istft(s_hat2 , hop_length=512 , win_length=1024)\n",
        "sf.write('/content/drive/MyDrive/cnn_output/cnn_02.wav', recon_sound2,sr)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wiw3JIKTBbmL",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "65361ba3-97b5-44d8-92da-b013c888bc49"
      },
      "source": [
        "s_hat_test3 = feedforward(transformed_x1 , output)\n",
        "recovered_x1 = recover_data(s_hat_test3 , (window_size - 1 , np.shape(s_hat_test3)[1]) , 1e-15)\n",
        "s_hat3 = recover_sound(X, mag_X , recovered_x1.T)\n",
        "recon_sound3 = librosa.istft(s_hat3 , hop_length=512 , win_length=1024)\n",
        "size_recon_sound3 = np.shape(recon_sound3)[0]"
      ],
      "execution_count": null,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:8: RuntimeWarning: invalid value encountered in true_divide\n",
            "  \n"
          ],
          "name": "stderr"
        }
      ]
    }
  ]
}